#!/usr/bin/env python3
# coding: utf-8
"""
把 objcopy 生成的“字节版 verilog hex”（可能带 @<byte_addr> 跳地址）
转换成“每行一条 32 位指令（小端拼接）”的 word 版 hex。
输出支持 @<word_index>（按“字地址”），适配 $readmemh 直接加载到 reg[31:0] mem[]。
"""

import sys, re

def main():
    if len(sys.argv) < 3:
        print("usage: pack_imem.py <in_hex_bytes> <out_hex_words>", file=sys.stderr)
        sys.exit(2)

    inp, outp = sys.argv[1], sys.argv[2]

    # 收集到一个“稀疏字节内存”：addr(byte) -> 0..255
    mem_bytes = {}
    cur_addr = 0  # 若文件起始没有 @，默认从 0 开始

    with open(inp, "r") as f:
        for line in f:
            s = line.strip()
            if not s:
                continue
            if s.startswith("@"):
                # 解析 @<byte_addr>
                try:
                    cur_addr = int(s[1:], 16)
                except ValueError:
                    print("WARN: bad @ address:", s, file=sys.stderr)
                    cur_addr = 0
                continue
            # 抓取所有“两个十六进制字符”的字节
            for bt in re.findall(r'(?i)\b[0-9a-f]{2}\b', s):
                mem_bytes[cur_addr] = int(bt, 16)
                cur_addr += 1

    if not mem_bytes:
        # 空文件：输出空文件即可
        open(outp, "w").close()
        return

    # 聚合为按“字”的稀疏映射：word_index -> [b0,b1,b2,b3]
    words = {}
    for addr, val in mem_bytes.items():
        wi = addr >> 2
        off = addr & 3
        if wi not in words:
            words[wi] = [0, 0, 0, 0]
        words[wi][off] = val

    # 以“字地址”升序输出；遇到不连续则写 @<word_index>
    with open(outp, "w") as g:
        prev_wi = None
        for wi in sorted(words.keys()):
            if prev_wi is None or wi != prev_wi + 1:
                g.write("@%08x\n" % wi)
            b0, b1, b2, b3 = words[wi]
            # 小端字节序 -> 文本大端 32bit：b3 b2 b1 b0
            g.write(("%02x%02x%02x%02x\n" % (b3, b2, b1, b0)).lower())
            prev_wi = wi

if __name__ == "__main__":
    main()
